﻿// ScreenProtecter.cpp : 定义应用程序的入口点。
//

#include "framework.h"
#include "ReadConfigFile.hpp"
#include "ScreenProtecter.h"
#include "threads.h"
#include "winReg.h"
#include "FaceFilter.h"
#include "hookcadp.h"

LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK MntrWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK PswWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
extern unsigned int __stdcall CamCapturingThread(void* __passbyData);
extern unsigned int __stdcall PauseTimer(void* p);



int WINAPI WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nCmdShow)
{

    if (OnlyOneRunning() == false) return false;
    _FILEREAD::ReadFile();
    // 注册窗口类
    RegisterWinClass(TEXT("MainWindow"), MainWndProc);
    RegisterWinClass(TEXT("Monitoring"), MntrWndProc);
    RegisterWinClass(TEXT("Password"), PswWndProc);

    //printf("bool:%d", BOOL_ISDEBUG);

    if (BOOL_ISDEBUG == true) {

        HANDLE hOutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);//Open console
        if (!hOutputHandle)
        {
            AllocConsole();
            freopen("conout$", "w", stdout);
        }
    }

    if (BOOL_ISBLOCKM == true) {
        EnableDebugPriv();
    }

    Global_hInstance = hInstance;

    
    ScreenWidth = GetSystemMetrics(SM_CXSCREEN);
    ScreenHeight = GetSystemMetrics(SM_CYSCREEN);
    BtnWidth = ScreenHeight / 15, BtnHeight = ScreenWidth / 30;

    // 创建窗口
    hwnd = CreateWindow(
        "MainWindow", // 类名
        "SP", // 窗口标题文字
        WS_POPUP|WS_EX_TOPMOST, // 窗口外观样式
        0, //38, // 窗口相对于父级的x坐标
        0, //20, // 窗口相对于父级的y坐标 GetSystemMetrics (SM_CXSCREEN)：获取屏幕宽度
        ScreenWidth,  // 窗口的宽度 GetSystemMetrics(SM_CYSCREEN)：获取屏幕高度
        ScreenHeight, // 窗口的高度
        NULL, // 没有父窗口
        NULL, // 没有菜单
        hInstance, // 当前应用程序的实例句柄
        NULL); // 没有附加数据
    RECT rect = { 0,0,BtnWidth * 3 , BtnHeight * 5 + 40 };

    AdjustWindowRect(&rect, WS_CAPTION,false);
    pswWindow = CreateWindow("Password", "PswWindow", WS_CHILD | WS_CAPTION | WS_SYSMENU  |WS_VISIBLE  | WS_EX_TOPMOST, 80, 80, rect.right - rect.left, rect.bottom - rect.top, hwnd, NULL, hInstance, NULL);
    SpmWindow = CreateWindow("Monitoring", "Monitoring", WS_CHILD|WS_VISIBLE| WS_CLIPSIBLINGS, 0, 0, 0, 0, hwnd, NULL, hInstance, NULL);
    

    if (hwnd == NULL|| SpmWindow == NULL)
    {
        MessageBox(NULL, "Cann't create windows", "Error", MB_ICONERROR);
        return 0;
    }

    

    keyrec = SetWindowsHookEx(
        WH_KEYBOARD_LL, // 监听类型【键盘消息】
        KeyboardProc,   // 处理函数
        hInstance,      // 当前实例句柄
        0               // 监听线程ID(NULL为全局监听)
    );
    // 判断是否成功
    if (keyrec == NULL)
    {
        MessageBox(hwnd, "text", TEXT("错误"), MB_OK);
    }

    /*Gdi+ initializing*/
    GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR m_gdiplusToken;
    GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);

    // 显示窗口
    ShowWindow(hwnd, SW_NORMAL);

    // 更新窗口
    UpdateWindow(hwnd);

    // 消息循环
    MSG msg;
   
    
    if (!cap.isOpened())
    {
        MessageBox(hwnd,"---Device Can Not Open---Break","Error", MB_ICONERROR| MB_OK);
        waitKey(1000);
        return 0;
    }

    passbyData _pbdata= { hwnd ,SpmWindow };//暂时只传一个参数，这里暂时不优化，后续可能会传多个参数
   
    HANDLE handle; 

    handle = (HANDLE)_beginthreadex(NULL, 0, CamCapturingThread, &_pbdata, 0, NULL);

    if (handle == NULL) {
        MessageBox(hwnd, "Failed to create thread", "Error", MB_ICONERROR | MB_OK);
        return 0;
    }

    while (GetMessage(&msg, NULL, 0, 0))
    {
        /*Begin transacting thread*/
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}



LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    LPPAINTSTRUCT ps = nullptr;
    switch (uMsg)
    {

    case WM_PAINT: {
        PAINTSTRUCT ps;
        HDC dc = BeginPaint(hwnd, &ps);
        __onDraw(dc);
        EndPaint(hwnd, &ps);
        ReleaseDC(hwnd, dc);
        break; }

    case WM_DESTROY:
        PostQuitMessage(uMsg);
        break;
    default:
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
        break;
    }
}


LRESULT CALLBACK MntrWndProc(HWND SpmWindow, UINT uMsg, WPARAM wParam, LPARAM lParam)
{

    switch (uMsg)
    {
    case WM_CREATE: {
        break;
    }
    case USER_REFREASH_MSG: {
        if (!frame.matPic.empty()) {
            MoveWindow(SpmWindow, (ScreenWidth - frame.matPic.cols) / 2, (ScreenHeight - frame.matPic.rows) / 2, frame.matPic.cols, frame.matPic.rows, false);
            HDC dc = GetDC(SpmWindow);
            __onMntrDraw(frame, dc);
            ReleaseDC(SpmWindow, dc);
        }
        break;
    }

    case WM_DESTROY:
        break;
    default:
        return DefWindowProc(SpmWindow, uMsg, wParam, lParam);
        break;
    }
}


LRESULT CALLBACK PswWndProc(HWND pswWindow, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    LPPAINTSTRUCT ps = nullptr;
    switch (uMsg)
    {
    case WM_CREATE: {
        passwordBuf.clear();
        int row = 1, col = 0;

        for (int i = 1; i <= 9; i++) {
            char TextName[] = { 'B','_' };
            wsprintf(TextName, "%d", i);
            hBtn[i] = CreateWindowEx(WS_EX_CLIENTEDGE, "BUTTON", TextName, WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, BtnWidth * col, BtnHeight * row, BtnWidth, BtnHeight, pswWindow, (HMENU)i, Global_hInstance, NULL);
            (i % 3 == 0) ? row++, col = 0 : col++;
        }

        hBtn[0] = CreateWindowEx(WS_EX_CLIENTEDGE, "BUTTON", "0", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, BtnWidth * 1, BtnHeight * row, BtnWidth, BtnHeight, pswWindow, (HMENU)0, Global_hInstance, NULL);
        hYes = CreateWindowEx(WS_EX_CLIENTEDGE, "BUTTON", "OK", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, BtnWidth * 0, BtnHeight * row, BtnWidth, BtnHeight, pswWindow, (HMENU)hmYes, Global_hInstance, NULL);
        hDel = CreateWindowEx(WS_EX_CLIENTEDGE, "BUTTON", "Del", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, BtnWidth * 2, BtnHeight * row, BtnWidth, BtnHeight, pswWindow, (HMENU)hmDel, Global_hInstance, NULL);
        hTextbox = CreateWindowEx(WS_EX_CLIENTEDGE, "STATIC", "", WS_BORDER | WS_CHILD | WS_VISIBLE, 0, 0, BtnWidth * 3, BtnHeight, pswWindow, (HMENU)10, Global_hInstance, NULL);
        row++;
        hCheckBox[0] = CreateWindowEx(WS_EX_CLIENTEDGE, "BUTTON", "Pause for 15 min", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON, 0, BtnHeight * row, BtnWidth * 3, 20, pswWindow, (HMENU)15, Global_hInstance, NULL);
        hCheckBox[1] = CreateWindowEx(WS_EX_CLIENTEDGE, "BUTTON", "Exit program", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON, 0, BtnHeight * row + 20, BtnWidth * 3, 20, pswWindow, (HMENU)16, Global_hInstance, NULL);
        SendMessage(hTextbox, WM_SETFONT, (WPARAM)_SetFont(), TRUE);
        SendMessage(hCheckBox[1], BM_CLICK, 0, 0);

        break;
    }

    case WM_COMMAND: {
        if ((HWND)lParam == hBtn[0]) passwordBuf.push_back('0');
        if ((HWND)lParam == hBtn[1]) passwordBuf.push_back('1');
        if ((HWND)lParam == hBtn[2]) passwordBuf.push_back('2');
        if ((HWND)lParam == hBtn[3]) passwordBuf.push_back('3');
        if ((HWND)lParam == hBtn[4]) passwordBuf.push_back('4');
        if ((HWND)lParam == hBtn[5]) passwordBuf.push_back('5');
        if ((HWND)lParam == hBtn[6]) passwordBuf.push_back('6');
        if ((HWND)lParam == hBtn[7]) passwordBuf.push_back('7');
        if ((HWND)lParam == hBtn[8]) passwordBuf.push_back('8');
        if ((HWND)lParam == hBtn[9]) passwordBuf.push_back('9');
        if ((HWND)lParam == hDel) { if (passwordBuf.length()) passwordBuf.pop_back(); }
        if ((HWND)lParam == hYes) {
            int len = GetWindowTextLength(hTextbox);
            char* str = (char*)malloc(len * sizeof(char) + 1);
            GetWindowText(hTextbox, str, len + 1);

            if (strcmp(str, passwordStr.data()) == 0) {
                if (SendMessage(hCheckBox[0], BM_GETCHECK, 0, 0) == BST_CHECKED && NeedsDetect == true) {

                    HANDLE handle = (HANDLE)_beginthreadex(NULL, 0, PauseTimer, NULL, 0, NULL);

                    if (handle == NULL) {
                        MessageBoxW(hwnd, L"Failed to create a thread", L"Error", MB_ICONERROR | MB_OK);
                        return 0;
                    }

                }
                if (SendMessage(hCheckBox[1], BM_GETCHECK, 0, 0) == BST_CHECKED) {
                    SendMessage(hwnd, WM_DESTROY, 0, 0);
                }
            }
            else {
                MessageBox(pswWindow, "Incorrect Passcode", "Error", MB_ICONERROR);
            }

            free(str);

        }
        SetWindowText(hTextbox, TEXT(passwordBuf.data()));
        break;
    }

    case WM_CLOSE:
        if(isNowActivate == false)
            ShowWindow(pswWindow, SW_HIDE);
        break;
    default:
        return DefWindowProc(pswWindow, uMsg, wParam, lParam);
        break;
    }
}


LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;
    if (nCode >= 0)
    {
        if (wParam == WM_KEYUP) {
            if (p->vkCode == VK_F12&&isNowActivate == false) {
                SetParent(pswWindow, NULL);
                ShowWindow(pswWindow, SW_NORMAL);
            }
        }
        else if (wParam == WM_SYSKEYUP) {
            if (p->vkCode == VK_LWIN || p->vkCode == VK_RWIN) {
                return 1;
            }
        }//It's useless

    }

    return CallNextHookEx(keyrec, nCode, wParam, lParam);
}





